package com.qdlc.p2p.biz.service.user.impl;

import javax.annotation.Resource;

import org.apache.avro.reflect.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.qd.p2p.adapter.AdaptedRequestHandleService;
import com.qd.p2p.adapter.enums.ResponseStatus;
import com.qd.p2p.adapter.param.BindingAccountCodeParameter;
import com.qd.p2p.adapter.response.BindingAccountCodeResponse;
import com.qd.p2p.sina.pay.enums.CertType;
import com.qd.p2p.sina.pay.enums.IdentityType;
import com.qd.p2p.sina.pay.enums.MemberType;
import com.qd.p2p.sina.pay.enums.VerifyType;
import com.qd.p2p.sina.pay.response.BlankResponse;
import com.qd.p2p.sina.pay.response.CreateActivateMemberResponse;
import com.qd.p2p.sina.pay.response.SetRealNameResponse;
import com.qd.p2p.sina.service.SinaPayService;
import com.qdlc.p2p.biz.service.user.UserRealNameService;
import com.qdlc.p2p.biz.util.UserLoginUtil;
import com.qdlc.p2p.common.core.ReturnResult;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.IdCard;
import com.qdlc.p2p.common.util.LogFactory;
import com.qdlc.p2p.common.util.OrderNoUtil;
import com.qdlc.p2p.common.util.SinaRSA;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.SystemConfigHelper.Nid;
import com.qdlc.p2p.dal.dao.UserDao;
import com.qdlc.p2p.dal.dao.UserIdentifyDao;
import com.qdlc.p2p.dal.dao.UserRealNameStatusDao;
import com.qdlc.p2p.dal.dto.RealNameStatus;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserIdentify;
import com.qdlc.p2p.dal.util.UserUtils;

/**
 * 用户实名认证
 * 
 * @author linya
 */
@Service
public class UserRealNameServiceImpl implements UserRealNameService {

	private static final Logger logger = LogFactory.EXCEPTION_LOGGER;

	private static final int STEP_0 = 0; // 开户
	private static final int STEP_1 = 1;
	private static final int STEP_2 = 2;
	private static final int STEP_3 = 3;
	private static final int STEP_4 = 4; // 认证成功

	@Resource
	UserIdentifyDao userIdentifyDao;

	@Resource
	SinaPayService sinaPayService;

	@Resource
	UserRealNameStatusDao userRealNameStatusDao;

	@Resource
	UserDao userDao;

	@Resource
	AdaptedRequestHandleService adaptedRequestHandleService;

	/**
	 * 在托管平台存在账户时，绑定已有账号，需要验证的验证码
	 */
	@Override
	public ReturnResult sendRealNameCode(String mobile) {
		BindingAccountCodeParameter param = new BindingAccountCodeParameter();
		param.setAccount(mobile);
		BindingAccountCodeResponse response = adaptedRequestHandleService.sendBindingAccountCode(param);
		if (ResponseStatus.SUCCESS.equals(response.getStatus())) {
			return ReturnResult.SUCCESS;
		} else {
			return new ReturnResult(response.getResponseMsg());
		}
	}

	/**
	 * 适配后的通用实名认证及绑定账户(绑定已有账号)
	 */
	@Override
	@Nullable
	public User realName(long userId, String cardId, String realName) {
		UserIdentify userIdentify = userIdentifyDao.findByUserId(userId);
		if (userIdentify.getRealNameStatus() != 1 && userIdentify.getRealNameStatus() != 2) {
			RealNameStatus stepModel = getStep(userId, cardId, realName);
			User user = saveRealName(stepModel, 2);
			return user;
		}
		return null;
	}

	/**
	 * sina的实名认证
	 */
	// @Override
	// public ReturnResult realName(long userId, String cardId, String realName) {
	//
	// RealNameStatus stepModel = getStep(userId, cardId, realName);
	//
	// if (stepModel.getStatus() == STEP_4) {
	// return new ReturnResult("您已实名认证，请勿重复操作!");
	// }
	//
	// ReturnResult result = null;
	//
	// try {
	// if (stepModel.getStatus() == STEP_0) {
	// result = step0(stepModel);
	// }
	//
	// if (stepModel.getStatus() == STEP_1) {
	// result = step1(stepModel);
	// }
	//
	// if (stepModel.getStatus() == STEP_2) {
	// result = step2(stepModel);
	// }
	//
	// if (stepModel.getStatus() == STEP_3) {
	// result = step3(stepModel);
	// }
	//
	// } catch (Exception e) {
	// result = new ReturnResult("实名认证失败,请稍后重试!");
	// }
	//
	// saveStep(stepModel);
	//
	// return result;
	// }

	/**
	 * 存放实名认证步骤
	 * 
	 * @param stepModel
	 */
	private void saveStep(RealNameStatus stepModel) {
		userRealNameStatusDao.merge(stepModel);
	}

	/**
	 * 获取实名认证步骤，如果没有，则新建一个实名认证步骤
	 * 
	 * @param userId
	 * @param cardId
	 * @param realName
	 * @return
	 */
	private RealNameStatus getStep(long userId, String cardId, String realName) {
		User user = UserUtils.getUserById(userId);
		// 如果，请求的cardId和保存的cardId不同,也需要重新开始认证
		RealNameStatus stepModel = new RealNameStatus();
		if (StringUtils.isBlank(user.getTppUserCustId())) {
			// 生成第三方ID
			String tppUserCustId = OrderNoUtil.getInstance().getSerialNumber();
			stepModel.setTppUserCustId(tppUserCustId);
		} else {
			stepModel.setTppUserCustId(user.getTppUserCustId());
		}
		stepModel.setStatus(0);
		stepModel.setUserId(userId);
		stepModel.setCardId(cardId);
		stepModel.setRealName(realName);

		return stepModel;
	}

	/**
	 * 实名认证步骤推进
	 */
	private void incrementStep(RealNameStatus stepModel) {
		stepModel.setStatus(stepModel.getStatus() + 1);
	}

	/**
	 * 第一步:开户
	 */
	private ReturnResult step0(RealNameStatus stepModel) {

		IdCard idCard = IdCard.getInstance(stepModel.getCardId());

		if ((idCard != null) && (idCard.getIdType() == IdCard.ID_NUM_V1)) {
			return new ReturnResult("不支持一代身份证!");
		}

		if (DateUtil.getLifeFullYear(idCard.getBirthday()) < 18) {
			return new ReturnResult("未满18周岁不能开户!");
		}

		String tppUserCustId = stepModel.getTppUserCustId();
		CreateActivateMemberResponse response = sinaPayService.createActiveMember(tppUserCustId, MemberType.person);
		if (response.success()) {
			incrementStep(stepModel);
		} else {
			return new ReturnResult("开户失败!");
		}

		return ReturnResult.SUCCESS;
	}

	/**
	 * 第二步:实名认证
	 */
	private ReturnResult step1(RealNameStatus stepModel) {
		String publicKey = SystemConfigHelper.getValue(Nid.CON_ENCRYPT);
		String cardId = SinaRSA.encryptByPublicKey(stepModel.getCardId(), publicKey);
		String realName = SinaRSA.encryptByPublicKey(stepModel.getRealName(), publicKey);
		SetRealNameResponse resp = sinaPayService.realName(stepModel.getTppUserCustId(), IdentityType.UID, CertType.IC,
				cardId, realName);
		if (resp.success()) {
			incrementStep(stepModel);
		} else {
			return new ReturnResult("用户实名认证失败!");
		}
		return ReturnResult.SUCCESS;
	}

	/**
	 * 第三步:绑定认证
	 */
	private ReturnResult step2(RealNameStatus stepModel) {
		String tppUserCustId = stepModel.getTppUserCustId();
		String publicKey = SystemConfigHelper.getValue(Nid.CON_ENCRYPT);
		User user = UserUtils.getUserById(stepModel.getUserId());
		String phoneRSA = SinaRSA.encryptByPublicKey(user.getMobilePhone(), publicKey);
		BlankResponse verifyresponse = sinaPayService.bindingVerify(tppUserCustId, IdentityType.UID, VerifyType.MOBILE,
				phoneRSA);
		if (verifyresponse.success()) {
			incrementStep(stepModel);
		} else {
			return new ReturnResult("绑定认证信息失败！");
		}
		return ReturnResult.SUCCESS;
	}

	/**
	 * 第四步: 保存认证数据
	 */
	private ReturnResult step3(RealNameStatus stepModel) {
		try {
			saveRealName(stepModel);
			incrementStep(stepModel);
		} catch (Exception e) {
			logger.info(stepModel.getUserId() + "开户本地处理失败, 请手动更新状态:" + stepModel);
			return new ReturnResult("系统繁忙，请稍后再试");
		}
		return ReturnResult.SUCCESS;
	}

	private User saveRealName(RealNameStatus stepModel, int status) {
		User user = UserUtils.getUserById(stepModel.getUserId());
		UserIdentify userIdentify = userIdentifyDao.findByUserId(user.getUserId());
		user.setRealName(stepModel.getRealName());
		user.setCardId(stepModel.getCardId());
		user.setTppUserCustId(stepModel.getTppUserCustId());
		userIdentify.setTppVerifyType("MOBILE");
		userIdentify.setRealNameStatus(status);
		userIdentify.setTppMobilePhoneStatus(status);
		userDao.update(user);
		userIdentifyDao.update(userIdentify);
		UserLoginUtil.heartbit(true);
		return user;
	}

	private User saveRealName(RealNameStatus stepModel) {
		return saveRealName(stepModel, 1);
	}

}
